struct domain *d;
rcu_read_lock(&domlist_read_lock);
- d = rcu_dereference(domain_hash[DOMAIN_HASH(dom)]);
- while ( d != NULL )
+
+ for ( d = rcu_dereference(domain_hash[DOMAIN_HASH(dom)]);
+ d != NULL;
+ d = rcu_dereference(d->next_in_hashbucket) )
{
if ( d->domain_id == dom )
{
d = NULL;
break;
}
- d = rcu_dereference(d->next_in_hashbucket);
}
+
rcu_read_unlock(&domlist_read_lock);
return d;
}
+struct domain *find_domain_rcu_lock(domid_t dom)
+{
+ struct domain *d;
+
+ rcu_read_lock(&domlist_read_lock);
+
+ for ( d = rcu_dereference(domain_hash[DOMAIN_HASH(dom)]);
+ d != NULL;
+ d = rcu_dereference(d->next_in_hashbucket) )
+ {
+ if ( d->domain_id == dom )
+ return d;
+ }
+
+ rcu_read_unlock(&domlist_read_lock);
+
+ return NULL;
+}
+
+
void domain_kill(struct domain *d)
{
domain_pause(d);
unsigned long initrd_start, unsigned long initrd_len,
char *cmdline);
+/*
+ * find_domain_rcu_lock() is more efficient than get_domain_by_id().
+ * This is the preferred function if the returned domain reference
+ * is short lived, but it cannot be used if the domain reference needs
+ * to be kept beyond the current scope (e.g., across a softirq).
+ * The returned domain reference must be discarded using domain_rcu_unlock().
+ */
+struct domain *find_domain_rcu_lock(domid_t dom);
+
+/* Finish a RCU critical region started by find_domain_rcu_lock(). */
+static inline void domain_rcu_unlock(struct domain *d)
+{
+ rcu_read_unlock(&domlist_read_lock);
+}
+
struct domain *get_domain_by_id(domid_t dom);
void domain_destroy(struct domain *d);
void domain_kill(struct domain *d);